/*
 * AplCadastrarEvento.java
 * 
 * Projeto: Kruskal - SRAC
 * LEDS - Laboratório de Engenharia e Desenvolvimento de Software
 * IFES - Instituto Federal do Espírito Santo - Campus Serra.
 */
package srac.controleeventos.cgt;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import srac.controleatividades.cdp.Aluno;
import srac.controleatividades.cdp.Usuario;
import srac.controleatividades.cgt.AplCadastroInterno;
import srac.controleeventos.cdp.*;
import srac.controleeventos.cgd.CertificadoDAOJPA;
import srac.controleeventos.cgd.EventoDAOJPA;
import util.utilitarioEndereco.cdp.*;
import util.utilitarioEndereco.cgd.BairroDAOJPA;
import util.utilitarioEndereco.cgd.EstadoDAOJPA;
import util.utilitarioEndereco.cgd.MunicipioDAOJPA;
import util.utilitarioPersistencia.DAO;
import util.utilitarioPersistencia.DAOFactory;

public class AplControleEvento {

    private DAO apDaoEvento = DAOFactory.obterDAO(Evento.class);
    private DAO apDaoParticipante = DAOFactory.obterDAO(Participante.class);
    private DAO apDaoMunicipio = DAOFactory.obterDAO(Municipio.class);
    private DAO apDaoBairro = DAOFactory.obterDAO(Bairro.class);
    private DAO apDaoEstado = DAOFactory.obterDAO(Estado.class);
    private DAO apDaoPais = DAOFactory.obterDAO(Pais.class);
    private DAO apDaoCertificado = DAOFactory.obterDAO(Certificado.class);
    private DAO apDaoTipoEvento = DAOFactory.obterDAO(TipoEvento.class);
    static private AplControleEvento instance = null;

    static public AplControleEvento getInstance() {
        if (instance == null) {
            instance = new AplControleEvento();
        }
        return instance;
    }

    public Evento incluirEvento(List<Object> args) throws Exception {
        Evento evento = new Evento();
        Endereco e = new Endereco();
        evento.setTipo((TipoEvento) args.get(0));
        evento.setNome((String) args.get(1));
        evento.setVagas((Integer) args.get(2));
        evento.setData((Calendar) args.get(3));
        evento.setStatusEvento(StatusEvento.Aberto);
        e = setEndereco(args);
        evento.setEndereco(e);

        evento = (Evento) apDaoEvento.salvar(evento);

        return evento;
    }

    /**
     * Altera os dados do Aluno no sistema
     * <p/>
     * @param evento
     * @return
     * @throws Exception
     */
    public Evento alterarEvento(Evento evento) throws Exception {
        return (Evento) apDaoEvento.salvar(evento);
    }
    
    public List<Evento> obterEvento() throws Exception {
        return (List<Evento>) apDaoEvento.obter(Evento.class);
    }
    
    public Boolean excluirEvento(Evento e) throws Exception {
        if (AplControleEvento.getInstance().obterEvento().isEmpty()) {
            return false;
        }


        apDaoEvento.excluir(e);
        return true;
    }

    /**
     * Inclui um participante em um evento
     * <p/>
     * @param participante
     * @return
     * @throws Exception
     */
    public Participante incluirParticipante(Participante participante) throws Exception {
        return (Participante) apDaoParticipante.salvar(participante);  
    }
    
    public void alterarParticipante(Participante participante) throws Exception
    {
        apDaoParticipante.salvar(participante);
    }

    public Endereco setEndereco(List<Object> listEndereco) {
        Endereco e = new Endereco();

        e.setCep((Long) listEndereco.get(4));
        e.setLogradouro((String) listEndereco.get(5));
        e.setNumero((Integer) (listEndereco.get(6)));
        e.setComplemento((String) listEndereco.get(7));
        e.setBairro((Bairro) listEndereco.get(11));
        e.getBairro().setMunicipio((Municipio) listEndereco.get(10));
        e.getBairro().getMunicipio().setEstado((Estado) listEndereco.get(9));
        e.getBairro().getMunicipio().getEstado().setPais((Pais) listEndereco.get(8));

        return e;
    }

    
    /**
     * Obtém uma lista com todos os Municipios
     * <p/>
     * @return
     */
    public List<Municipio> obterMunicipio(Estado estado) throws Exception {
        return (List<Municipio>) ((MunicipioDAOJPA) apDaoMunicipio).obter(estado);
    }

    /**
     * Obtém uma lista com todos os Países
     * <p/>
     * @return
     */
    public List<Pais> obterPais() throws Exception {
        return (List<Pais>) apDaoPais.obter(Pais.class);
    }

    /**
     * Obtém uma lista com todos os Bairros
     * <p/>
     * @return
     */
    public List<Bairro> obterBairro(Municipio municipio) throws Exception {
        return (List<Bairro>) ((BairroDAOJPA) apDaoBairro).obter(municipio);
    }

    /**
     * Obtém uma lista com todos os Estados
     * <p/>
     * @return
     */
    public List<Estado> obterEstados(Pais pais) throws Exception {
        return (List<Estado>) ((EstadoDAOJPA) apDaoEstado).obter(pais);
    }

    public List<Evento> obterEventoAberto() {
        return (List<Evento>) ((EventoDAOJPA) apDaoEvento).obterEventoAberto();
    }

    public List<Participante> obterEventoParticipante(Evento e) {
        return (List<Participante>) ((EventoDAOJPA) apDaoEvento).obterEventoParticipante(e);
    }
    
    public List<Certificado> obterCertificados(Participante p)
    {
        return (List<Certificado>) ((CertificadoDAOJPA) apDaoCertificado).obterCertificados(p);
    }
    

    public boolean inscreverAlunoEvento(Usuario u, Evento e) throws Exception {
        Aluno a = AplCadastroInterno.getInstance().obterAluno(u);
        if(!verificarExistenciaInscricao(a, e))
        {
            Participante p = new Participante();
            p.setNome(a.getNome());
            p.setEmail(a.getEmail());
            p.setCpf(a.getCpf());
            e.setVagas(e.getVagas()-1);
            p.setEvento(e);
            p.setPresente(false);
            a.getParticipacoes().add(incluirParticipante(p));
            AplCadastroInterno.getInstance().alterarAluno(a);
            alterarEvento(e);
            return true;
        }
        return false;
    }
    
    public void aterarPresenca(List<Participante> participantes, boolean b) throws Exception {
        for (Participante part : participantes) {
            part.setPresente(b);
            alterarParticipante(part);
        }
    }
    
    public boolean verificarExistenciaInscricao(Aluno a, Evento e)
    {
        for (Participante p : a.getParticipacoes()) {
            if(p.getEvento().equals(e))
            {
                return true;
            }
        }
        return false;
    }

    public void emitirCertificado(List<Participante> participantes) throws Exception {
        for (Participante p : participantes) {
            if(obterCertificados(p).isEmpty())
            {
                if(p.getPresente())
                {
                    Certificado c = new Certificado();
                    c.setEvento(p.getEvento());
                    c.setParticipante(p);
                    AplEnviarCertificado.gerarPdf(c);
                    apDaoCertificado.salvar(c);
                }
            }
        }
       
    }

    public void encerrarEvento(Evento e) throws Exception {
        e.setStatusEvento(StatusEvento.Encerrado);
        apDaoEvento.salvar(e);
    }

    public List<Evento> obterEventosAtividade(Aluno obj) {
        List<Evento> eventos = new ArrayList<Evento>();
        for (Participante p  : obj.getParticipacoes()) {
            List<Certificado> c = obterCertificados(p);
            if(!c.isEmpty())
            {
                if(c.get(0).getEvento().getStatusEvento().equals(StatusEvento.Encerrado))
                {
                    eventos.add(c.get(0).getEvento());
                }
            }
        }
        return eventos;
    }
    

    public List<TipoEvento> obterTipoEventos() throws Exception
    {
        return apDaoTipoEvento.obter(TipoEvento.class);
    }
}
